﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using WebChatApi.Common.Interface;

namespace WebChatApi.Common
{
    /// <summary>
    /// Class for user behavior action track.
    /// </summary>
    [DataContract]
    [KnownType(typeof(WebActionTrack))]
    [KnownType(typeof(ApplicationSource))]
    public class UserBehaviorTrack : WebActionTrack
    {
        /// <summary>
        /// Enum for Behavior types
        /// </summary>
        [DataContract]
        public enum BehaviorType
        {
            /// <summary>
            /// Value indicating type is Unknown.
            /// </summary>
            [EnumMember]
            Unknown = 0,
            /// <summary>
            /// Value indicating type is OpenEmail.
            /// </summary>
            [EnumMember]
            OpenEmail = 1,
            /// <summary>
            /// Value indicating type is ClickPushNotification.
            /// </summary>
            [EnumMember]
            ClickPushNotification = 2,
            /// <summary>
            /// Value indicating type is ClickEmailLink.
            /// </summary>
            [EnumMember]
            ClickEmailLink = 4,
            /// <summary>
            /// Value indicating type is AccessService.
            /// </summary>
            [EnumMember]
            AccessService = 8,
            /// <summary>
            /// Value indicating type is LocalActivity.
            /// </summary>
            [EnumMember]
            LocalActivity = 16,
            /// <summary>
            /// Value indicating type is Local Activity with service operation.
            /// </summary>
            [EnumMember]
            LocalActivityWithServiceOperation = LocalActivity + AccessService
        }

        #region Properties

        /// <summary>
        /// Gets or sets the user key.
        /// </summary>
        /// <value>The user key.</value>
        [DataMember]
        public new Guid? UserKey
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the application.
        /// e.g.: Jibo App, Patient Manager, Health Center, etc.
        /// </summary>
        /// <value>
        /// The application.
        /// </value>
        [DataMember]
        public string Application
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the platform.
        /// Use platform scope of <see cref="ApplicationSource"/> values only.
        /// (Value from 0x1 to 0xF)
        /// </summary>
        /// <value>
        /// The platform.
        /// </value>
        [DataMember]
        public ApplicationSource Platform
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the device info.
        /// e.g.: HTC A3360, iPhone4S, iPad2, etc.
        /// This property is for mobile only.
        /// </summary>
        /// <value>
        /// The device info.
        /// </value>
        [DataMember]
        public string DeviceInfo
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the login session identity.
        /// It should be a unique value for identifying the different session for same user.
        /// It could be the SessionKey in AuthorityService, or mobile devices can generate a random long code.
        /// </summary>
        /// <value>
        /// The login session identity.
        /// </value>
        [DataMember]
        public string LoginSessionIdentity
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the device id.
        /// The device hardware id, such as IMEI code.
        /// This property is for mobile only.
        /// </summary>
        /// <value>
        /// The device id.
        /// </value>
        [DataMember]
        public string DeviceId
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the type.
        /// The type for the activity
        /// </summary>
        /// <value>
        /// The type.
        /// </value>
        [DataMember]
        public BehaviorType Type
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the activity category.
        /// </summary>
        /// <value>
        /// The activity category.
        /// </value>
        [DataMember]
        public string ActivityCategory
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the activity.
        /// </summary>
        /// <value>
        /// The activity.
        /// </value>
        [DataMember]
        public string Activity
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the event.
        /// </summary>
        /// <value>
        /// The event.
        /// </value>
        [DataMember]
        public string Event
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the tag.
        /// </summary>
        /// <value>
        /// The tag.
        /// </value>
        [DataMember]
        public string Tag
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the OS info.
        /// e.g.: iOS 6.1.0, Android 2.4.1, etc.
        /// This property is for apps only.
        /// </summary>
        /// <value>
        /// The OS info.
        /// </value>
        [DataMember]
        public string OSInfo
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the channel.
        /// The identity for publisher.
        /// e.g.: 91, 360, Google, QQ, etc.
        /// </summary>
        /// <value>
        /// The channel.
        /// </value>
        [DataMember]
        public string Channel
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the customized field1.
        /// </summary>
        /// <value>
        /// The customized field1.
        /// </value>
        [DataMember]
        public string CustomizedField1
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the customized field2.
        /// </summary>
        /// <value>
        /// The customized field2.
        /// </value>
        [DataMember]
        public string CustomizedField2
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the customized field3.
        /// </summary>
        /// <value>
        /// The customized field3.
        /// </value>
        [DataMember]
        public string CustomizedField3
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the customized field4.
        /// </summary>
        /// <value>
        /// The customized field4.
        /// </value>
        [DataMember]
        public string CustomizedField4
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the customized field5.
        /// </summary>
        /// <value>
        /// The customized field5.
        /// </value>
        [DataMember]
        public string CustomizedField5
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the customized field6.
        /// </summary>
        /// <value>
        /// The customized field6.
        /// </value>
        [DataMember]
        public string CustomizedField6
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the customized field7.
        /// </summary>
        /// <value>
        /// The customized field7.
        /// </value>
        [DataMember]
        public string CustomizedField7
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the customized field8.
        /// </summary>
        /// <value>
        /// The customized field8.
        /// </value>
        [DataMember]
        public string CustomizedField8
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the device local time.
        /// </summary>
        /// <value>
        /// The device local time.
        /// </value>
        [DataMember]
        public DateTime? DeviceLocalTime
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the time zone offset.
        /// e.g.: 8 (GMT+8), -4 (GMT-4)
        /// </summary>
        /// <value>The time zone offset.</value>
        [DataMember]
        public float? TimeZoneOffset
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the culture information.
        /// e.g.: zh-CN, en-US, zh-TW
        /// </summary>
        /// <value>The culture information.</value>
        [DataMember]
        public string CultureInfo
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the user identity.
        /// For the old services, this property is for saving UserId.
        /// For the new services, this property is for login name.
        /// </summary>
        /// <value>
        /// The user identity.
        /// </value>
        [DataMember]
        public string UserIdentity
        {
            get;
            set;
        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="UserBehaviorTrack"/> class.
        /// </summary>
        public UserBehaviorTrack(BehaviorType type = BehaviorType.Unknown)
            : base()
        {
            this.Type = type;
        }
    }
}
